#only save caller registers
.macro TRAP_ENTRY
  addi sp, sp, -16*32

  sw x1,  0*32(sp)
  sw x5,  1*32(sp)
  sw x6,  2*32(sp)
  sw x7,  3*32(sp)
  sw x10, 4*32(sp)
  sw x11, 5*32(sp)
  sw x12, 6*32(sp)
  sw x13, 7*32(sp)
  sw x14, 8*32(sp)
  sw x15, 9*32(sp)
  sw x16, 10*32(sp)
  sw x17, 11*32(sp)
  sw x28, 12*32(sp)
  sw x29, 13*32(sp)
  sw x30, 14*32(sp)
  sw x31, 15*32(sp)
.endm

#resw caller registers
.macro TRAP_EXIT
  lw x1,  0*32(sp)
  lw x5,  1*32(sp)
  lw x6,  2*32(sp)
  lw x7,  3*32(sp)
  lw x10, 4*32(sp)
  lw x11, 5*32(sp)
  lw x12, 6*32(sp)
  lw x13, 7*32(sp)
  lw x14, 8*32(sp)
  lw x15, 9*32(sp)
  lw x16, 10*32(sp)
  lw x17, 11*32(sp)
  lw x28, 12*32(sp)
  lw x29, 13*32(sp)
  lw x30, 14*32(sp)
  lw x31, 15*32(sp)

  addi sp, sp, 16*32
  mret
.endm


.global exception_handler
.weak exception_handler
.set exception_handler, __temp_irq_handler

.global software_handler
.weak software_handler
.set software_handler, __temp_irq_handler

.global timer_handler
.weak timer_handler
.set timer_handler, __temp_irq_handler

.global external_handler
.weak external_handler
.set external_handler, __temp_irq_handler

.global nmi_handler
.weak nmi_handler
.set nmi_handler, __temp_irq_handler

.global fast_irq0_handler
.weak fast_irq0_handler
.set fast_irq0_handler, __temp_irq_handler

.global fast_irq1_handler
.weak fast_irq1_handler
.set fast_irq1_handler, __temp_irq_handler

.global fast_irq2_handler
.weak fast_irq2_handler
.set fast_irq2_handler, __temp_irq_handler

.global fast_irq3_handler
.weak fast_irq3_handler
.set fast_irq3_handler, __temp_irq_handler

.global fast_irq4_handler
.weak fast_irq4_handler
.set fast_irq4_handler, __temp_irq_handler

.global fast_irq5_handler
.weak fast_irq5_handler
.set fast_irq5_handler, __temp_irq_handler

.global fast_irq6_handler
.weak fast_irq6_handler
.set fast_irq6_handler, __temp_irq_handler

.global fast_irq7_handler
.weak fast_irq7_handler
.set fast_irq7_handler, __temp_irq_handler

.global fast_irq8_handler
.weak fast_irq8_handler
.set fast_irq8_handler, __temp_irq_handler

.global fast_irq9_handler
.weak fast_irq9_handler
.set fast_irq9_handler, __temp_irq_handler

.global fast_irq10_handler
.weak fast_irq10_handler
.set fast_irq10_handler, __temp_irq_handler

.global fast_irq11_handler
.weak fast_irq11_handler
.set fast_irq11_handler, __temp_irq_handler

.global fast_irq12_handler
.weak fast_irq12_handler
.set fast_irq12_handler, __temp_irq_handler

.global fast_irq13_handler
.weak fast_irq13_handler
.set fast_irq13_handler, __temp_irq_handler

.global fast_irq14_handler
.weak fast_irq14_handler
.set fast_irq14_handler, __temp_irq_handler

.global fast_irq15_handler
.weak fast_irq15_handler
.set fast_irq15_handler, __temp_irq_handler


/*external interrupt*/
//#define PLIC_VEC
#ifdef PLIC_VEC
//invalid                           /* 0*/
.global timer0_intr_handler         /* 1*/
.weak timer0_intr_handler
.set timer0_intr_handler, __temp_irq_handler

.global timer1_intr_handler         /* 2*/
.weak timer1_intr_handler
.set timer1_intr_handler, __temp_irq_handler

.global timer2_intr_handler         /* 3*/
.weak timer2_intr_handler
.set timer2_intr_handler, __temp_irq_handler

.global timer3_intr_handler         /* 4*/
.weak timer3_intr_handler
.set timer3_intr_handler, __temp_irq_handler

.global timer4_intr_handler         /* 5*/
.weak timer4_intr_handler
.set timer4_intr_handler, __temp_irq_handler

.global timer5_intr_handler         /* 6*/
.weak timer5_intr_handler
.set timer5_intr_handler, __temp_irq_handler

.global timer6_intr_handler         /* 7*/
.weak timer6_intr_handler
.set timer6_intr_handler, __temp_irq_handler

.global timer7_intr_handler         /* 8*/
.weak timer7_intr_handler
.set timer7_intr_handler, __temp_irq_handler

.global assi0_intr_handler          /* 9*/
.weak assi0_intr_handler
.set assi0_intr_handler, __temp_irq_handler

.global assi1_intr_handler          /*10*/
.weak assi1_intr_handler
.set assi1_intr_handler, __temp_irq_handler

.global assi2_intr_handler          /*11*/
.weak assi2_intr_handler
.set assi2_intr_handler, __temp_irq_handler

.global assi3_intr_handler          /*12*/
.weak assi3_intr_handler
.set assi3_intr_handler, __temp_irq_handler

.global assi4_intr_handler          /*13*/
.weak assi4_intr_handler
.set assi4_intr_handler, __temp_irq_handler

.global assi5_intr_handler          /*14*/
.weak assi5_intr_handler
.set assi5_intr_handler, __temp_irq_handler

.global i2s_intr_handler            /*15*/
.weak i2s_intr_handler
.set i2s_intr_handler, __temp_irq_handler

.global iwdt_intr_handler           /*16*/
.weak iwdt_intr_handler
.set iwdt_intr_handler, __temp_irq_handler

.global rtc_intr_handler            /*17*/
.weak rtc_intr_handler
.set rtc_intr_handler, __temp_irq_handler

.global DMAC0_IRQHandler            /*18*/
.weak DMAC0_IRQHandler
.set DMAC0_IRQHandler, __temp_irq_handler

.global ewm_intr_handler            /*19*/
.weak ewm_intr_handler
.set ewm_intr_handler, __temp_irq_handler

.global lpitimer0_intr_handler      /*20*/
.weak lpitimer0_intr_handler
.set lpitimer0_intr_handler, __temp_irq_handler

.global lpitimer1_intr_handler      /*21*/
.weak lpitimer1_intr_handler
.set lpitimer1_intr_handler, __temp_irq_handler

.global lpitimer2_intr_handler      /*22*/
.weak lpitimer2_intr_handler
.set lpitimer2_intr_handler, __temp_irq_handler

.global lpitimer3_intr_handler      /*23*/
.weak lpitimer3_intr_handler
.set lpitimer3_intr_handler, __temp_irq_handler

.global cpuwakeup_intr_handler      /*24*/
.weak cpuwakeup_intr_handler
.set cpuwakeup_intr_handler, __temp_irq_handler

.global qei0_intr_handler           /*25*/
.weak qei0_intr_handler
.set qei0_intr_handler, __temp_irq_handler

.global gpioa_intr_handler          /*26*/
.weak gpioa_intr_handler
.set gpioa_intr_handler, __temp_irq_handler

.global gpiob_intr_handler          /*27*/
.weak gpiob_intr_handler
.set gpiob_intr_handler, __temp_irq_handler

.global gpioc_intr_handler          /*28*/
.weak gpioc_intr_handler
.set gpioc_intr_handler, __temp_irq_handler

.global gpiod_intr_handler          /*29*/
.weak gpiod_intr_handler
.set gpiod_intr_handler, __temp_irq_handler

//invalid                           /*30*/
.global qei1_intr_handler           /*31*/
.weak qei1_intr_handler
.set qei1_intr_handler, __temp_irq_handler

.global lpi2c_intr_handler          /*32*/
.weak lpi2c_intr_handler
.set lpi2c_intr_handler, __temp_irq_handler

.global lpspi_intr_handler          /*33*/
.weak lpspi_intr_handler
.set lpspi_intr_handler, __temp_irq_handler

.global eflash_intr_handler         /*34*/
.weak eflash_intr_handler
.set eflash_intr_handler, __temp_irq_handler

//invalid                           /*35*/
//invalid                           /*36*/
//invalid                           /*37*/
.global mpu_err_intr_handler        /*38*/
.weak mpu_err_intr_handler
.set mpu_err_intr_handler, __temp_irq_handler

.global erm_intr_handler            /*39*/
.weak erm_intr_handler
.set erm_intr_handler, __temp_irq_handler

.global lptimer0_intr_handler       /*40*/
.weak lptimer0_intr_handler
.set lptimer0_intr_handler, __temp_irq_handler

.global lptimer1_intr_handler       /*41*/
.weak lptimer1_intr_handler
.set lptimer1_intr_handler, __temp_irq_handler

.global lptimer2_intr_handler       /*42*/
.weak lptimer2_intr_handler
.set lptimer2_intr_handler, __temp_irq_handler

.global clk_fault_intr_handler      /*43*/
.weak clk_fault_intr_handler
.set clk_fault_intr_handler, __temp_irq_handler

.global luart_intr_handler          /*44*/
.weak luart_intr_handler
.set luart_intr_handler, __temp_irq_handler

.global bor_intr_handler            /*45*/
.weak bor_intr_handler
.set bor_intr_handler, __temp_irq_handler

.global CAN0_IRQHandler           /*46*/
.weak CAN0_IRQHandler
.set CAN0_IRQHandler, __temp_irq_handler

.global CAN1_IRQHandler           /*47*/
.weak CAN1_IRQHandler
.set CAN1_IRQHandler, __temp_irq_handler

.global CAN2_IRQHandler           /*48*/
.weak CAN2_IRQHandler
.set CAN2_IRQHandler, __temp_irq_handler

//invalid                           /*49*/
//invalid                           /*50*/
.global mtu0_tgia0_handler          /*51*/
.weak mtu0_tgia0_handler
.set mtu0_tgia0_handler, __temp_irq_handler

.global mtu0_tgib0_handler          /*52*/
.weak mtu0_tgib0_handler
.set mtu0_tgib0_handler, __temp_irq_handler

.global mtu0_tgic0_handler          /*53*/
.weak mtu0_tgic0_handler
.set mtu0_tgic0_handler, __temp_irq_handler

.global mtu0_tgid0_handler          /*54*/
.weak mtu0_tgid0_handler
.set mtu0_tgid0_handler, __temp_irq_handler

.global mtu0_tgiv0_handler          /*55*/
.weak mtu0_tgiv0_handler
.set mtu0_tgiv0_handler, __temp_irq_handler

.global mtu0_tgie0_handler          /*56*/
.weak mtu0_tgie0_handler
.set mtu0_tgie0_handler, __temp_irq_handler

.global mtu0_tgif0_handler          /*57*/
.weak mtu0_tgif0_handler
.set mtu0_tgif0_handler, __temp_irq_handler

.global mtu0_tgia1_handler          /*58*/
.weak mtu0_tgia1_handler
.set mtu0_tgia1_handler, __temp_irq_handler

.global mtu0_tgib1_handler          /*59*/
.weak mtu0_tgib1_handler
.set mtu0_tgib1_handler, __temp_irq_handler

.global mtu0_tgiv1_handler          /*60*/
.weak mtu0_tgiv1_handler
.set mtu0_tgiv1_handler, __temp_irq_handler

.global mtu0_tgiu1_handler          /*61*/
.weak mtu0_tgiu1_handler
.set mtu0_tgiu1_handler, __temp_irq_handler

.global mtu0_tgia2_handler          /*62*/
.weak mtu0_tgia2_handler
.set mtu0_tgia2_handler, __temp_irq_handler

.global mtu0_tgib2_handler          /*63*/
.weak mtu0_tgib2_handler
.set mtu0_tgib2_handler, __temp_irq_handler

.global mtu0_tgiv2_handler          /*64*/
.weak mtu0_tgiv2_handler
.set mtu0_tgiv2_handler, __temp_irq_handler

.global mtu0_tgiu2_handler          /*65*/
.weak mtu0_tgiu2_handler
.set mtu0_tgiu2_handler, __temp_irq_handler

.global mtu0_tgia3_handler          /*66*/
.weak mtu0_tgia3_handler
.set mtu0_tgia3_handler, __temp_irq_handler

.global mtu0_tgib3_handler          /*67*/
.weak mtu0_tgib3_handler
.set mtu0_tgib3_handler, __temp_irq_handler

.global mtu0_tgic3_handler          /*68*/
.weak mtu0_tgic3_handler
.set mtu0_tgic3_handler, __temp_irq_handler

.global mtu0_tgid3_handler          /*69*/
.weak mtu0_tgid3_handler
.set mtu0_tgid3_handler, __temp_irq_handler

.global mtu0_tgiv3_handler          /*70*/
.weak mtu0_tgiv3_handler
.set mtu0_tgiv3_handler, __temp_irq_handler

.global mtu0_tgia4_handler          /*71*/
.weak mtu0_tgia4_handler
.set mtu0_tgia4_handler, __temp_irq_handler

.global mtu0_tgib4_handler          /*72*/
.weak mtu0_tgib4_handler
.set mtu0_tgib4_handler, __temp_irq_handler

.global mtu0_tgic4_handler          /*73*/
.weak mtu0_tgic4_handler
.set mtu0_tgic4_handler, __temp_irq_handler

.global mtu0_tgid4_handler          /*74*/
.weak mtu0_tgid4_handler
.set mtu0_tgid4_handler, __temp_irq_handler

.global mtu0_tgiv4_handler          /*75*/
.weak mtu0_tgiv4_handler
.set mtu0_tgiv4_handler, __temp_irq_handler

.global mtu0_tgiu5_handler          /*76*/
.weak mtu0_tgiu5_handler
.set mtu0_tgiu5_handler, __temp_irq_handler

.global mtu0_tgiv5_handler          /*77*/
.weak mtu0_tgiv5_handler
.set mtu0_tgiv5_handler, __temp_irq_handler

.global mtu0_tgiw5_handler          /*78*/
.weak mtu0_tgiw5_handler
.set mtu0_tgiw5_handler, __temp_irq_handler

.global mtu0_tgia6_handler          /*79*/
.weak mtu0_tgia6_handler
.set mtu0_tgia6_handler, __temp_irq_handler

.global mtu0_tgib6_handler          /*80*/
.weak mtu0_tgib6_handler
.set mtu0_tgib6_handler, __temp_irq_handler

.global mtu0_tgic6_handler          /*81*/
.weak mtu0_tgic6_handler
.set mtu0_tgic6_handler, __temp_irq_handler

.global mtu0_tgid6_handler          /*82*/
.weak mtu0_tgid6_handler
.set mtu0_tgid6_handler, __temp_irq_handler

.global mtu0_tgiv6_handler          /*83*/
.weak mtu0_tgiv6_handler
.set mtu0_tgiv6_handler, __temp_irq_handler

.global mtu0_tgia7_handler          /*84*/
.weak mtu0_tgia7_handler
.set mtu0_tgia7_handler, __temp_irq_handler

.global mtu0_tgib7_handler          /*85*/
.weak mtu0_tgib7_handler
.set mtu0_tgib7_handler, __temp_irq_handler

.global mtu0_tgic7_handler          /*86*/
.weak mtu0_tgic7_handler
.set mtu0_tgic7_handler, __temp_irq_handler

.global mtu0_tgid7_handler          /*87*/
.weak mtu0_tgid7_handler
.set mtu0_tgid7_handler, __temp_irq_handler

.global mtu0_tgiv7_handler          /*88*/
.weak mtu0_tgiv7_handler
.set mtu0_tgiv7_handler, __temp_irq_handler

.global pdb0_intr_handler           /*89*/
.weak pdb0_intr_handler
.set pdb0_intr_handler, __temp_irq_handler

.global pdb1_intr_handler           /*90*/
.weak pdb1_intr_handler
.set pdb1_intr_handler, __temp_irq_handler

//invalid                           /*91*/
//invalid                           /*92*/
//invalid                           /*93*/
//invalid                           /*94*/
//invalid                           /*95*/
.global adc0_smaple_handler         /*96*/
.weak adc0_smaple_handler
.set adc0_smaple_handler, __temp_irq_handler

.global adc1_smaple_handler         /*97*/
.weak adc1_smaple_handler
.set adc1_smaple_handler, __temp_irq_handler

.global adc0_arbitration_handler    /*98*/
.weak adc0_arbitration_handler
.set adc0_arbitration_handler, __temp_irq_handler

.global adc1_arbitration_handler    /*99*/
.weak adc1_arbitration_handler
.set adc1_arbitration_handler, __temp_irq_handler

.global iin0_intr_handler           /*100*/
.weak iin0_intr_handler
.set iin0_intr_handler, __temp_irq_handler

.global iin1_intr_handler           /*101*/
.weak iin1_intr_handler
.set iin1_intr_handler, __temp_irq_handler

.global lptimer_intr_handler        /*102*/
.weak lptimer_intr_handler
.set lptimer_intr_handler, __temp_irq_handler

.global intc_adc1_handler           /*103*/
.weak intc_adc1_handler
.set intc_adc1_handler, __temp_irq_handler

.global hsm_intr_handler            /*104*/
.weak hsm_intr_handler
.set hsm_intr_handler, __temp_irq_handler

.global intc_cmp_handler            /*105*/
.weak intc_cmp_handler
.set intc_cmp_handler, __temp_irq_handler

.global intc_adc0_handler           /*106*/
.weak intc_adc0_handler
.set intc_adc0_handler, __temp_irq_handler

.global adc0_ts_irq_handler         /*107*/
.weak adc0_ts_irq_handler
.set adc0_ts_irq_handler, __temp_irq_handler

.global adc0_ts_irqh_handler        /*108*/
.weak adc0_ts_irqh_handler
.set adc0_ts_irqh_handler, __temp_irq_handler

.global adc0_ts_irql_handler        /*109*/
.weak adc0_ts_irql_handler
.set adc0_ts_irql_handler, __temp_irq_handler

.global adc1_ts_irq_handler         /*110*/
.weak adc1_ts_irq_handler
.set adc1_ts_irq_handler, __temp_irq_handler

.global adc1_ts_irqh_handler        /*111*/
.weak adc1_ts_irqh_handler
.set adc1_ts_irqh_handler, __temp_irq_handler

.global adc1_ts_irql_handler        /*112*/
.weak adc1_ts_irql_handler
.set adc1_ts_irql_handler, __temp_irq_handler

.global poen_oei1_irq_handler       /*113*/
.weak poen_oei1_irq_handler
.set poen_oei1_irq_handler, __temp_irq_handler

.global poen_oei2_irq_handler       /*114*/
.weak poen_oei2_irq_handler
.set poen_oei2_irq_handler, __temp_irq_handler

.global poen_oei3_irq_handler       /*115*/
.weak poen_oei3_irq_handler
.set poen_oei3_irq_handler, __temp_irq_handler

.global cmp_intr_handler            /*116*/
.weak cmp_intr_handler
.set cmp_intr_handler, __temp_irq_handler

.global cmu_intr_handler            /*117*/
.weak cmu_intr_handler
.set cmu_intr_handler, __temp_irq_handler

.global pllloss_intr_handler        /*118*/
.weak pllloss_intr_handler
.set pllloss_intr_handler, __temp_irq_handler
#endif







.section .text.default_exc_handler, "ax", @progbits
.global default_exc_handler
.weak default_exc_handler
default_exc_handler:
  TRAP_ENTRY
  csrr a0, mcause
  csrr a1, mepc
  call handle_trap
  csrw mepc, a0
  TRAP_EXIT

.weak handle_trap
handle_trap:
1:
  j 1b

.section .text.__temp_irq_handler, "ax", @progbits
.global __temp_irq_handler
.weak __temp_irq_handler
__temp_irq_handler:
  TRAP_ENTRY
  csrr a0, mcause
  csrr a1, mepc
  call handle_interrupt
  csrw mepc, a0
  TRAP_EXIT

.weak handle_interrupt
handle_interrupt:
1:
  j 1b